
#!/usr/bin/env python3

import os
import hashlib
import sys
import re
from collections import defaultdict

RED = "\033[1;31m"
GREEN = "\033[1;32m"
RESET = "\033[0m"


def get_build_path(log):
    # build完成后自动获取文件路径
    if not log:
        return False, None
    for line in log.splitlines():
        match = re.search(r"Package folder (.*)$", line)
        if match:
            print(line)
            return True, match.group(1)
    print(f"{RED} 未找到Package folder！！！{RESET}")
    return False, None


def calculate_md5(file_path):
    """计算文件的MD5值"""
    hash_md5 = hashlib.md5()
    try:
        with open(file_path, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()
    except (IOError, OSError) as e:
        print(f"无法读取文件 {file_path}: {e}")
        return None

def get_files_md5(directory):
    """获取目录下所有文件的MD5值"""
    files_md5 = {}
    if not os.path.isdir(directory):
        print(f"错误: {directory} 不是有效的目录")
        return files_md5
    
    print(f"正在扫描目录: {directory}")
    for root, _, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            # 计算相对路径，便于比较不同目录下的相同文件
            rel_path = os.path.relpath(file_path, directory)
            md5_value = calculate_md5(file_path)
            if md5_value:
                files_md5[rel_path] = md5_value
    
    return files_md5

def compare_directories(*directories):
    """比较多个目录的文件MD5值"""
    # 获取所有目录的文件MD5信息
    md5_dicts = []
    for directory in directories:
        md5_dicts.append(get_files_md5(directory))
    
    # 获取所有文件的并集
    all_files = set()
    for md5_dict in md5_dicts:
        all_files.update(md5_dict.keys())
    
    # 存储不一致的文件信息
    inconsistent_files = []
    
    print("\n开始比较MD5值...")
    for file in sorted(all_files):
        # 获取每个目录中该文件的MD5值
        md5_values = []
        for md5_dict in md5_dicts:
            md5_values.append(md5_dict.get(file, "文件不存在"))
        
        # 检查所有MD5值是否一致
        if len(set(md5_values)) == 1 and "文件不存在" not in md5_values:
            continue
        
        # 如果文件在所有目录中都不存在，也跳过
        if all(md5 == "文件不存在" for md5 in md5_values):
            continue
        
        file_info = {'file': file}
        for i, directory in enumerate(directories):
            file_info[f'dir{i+1}_md5'] = md5_values[i]
            file_info[f'dir{i+1}_name'] = directory
        
        inconsistent_files.append(file_info)
    
    return inconsistent_files, directories

def print_results(inconsistent_files, directories):
    """打印比较结果"""
    if not inconsistent_files:
        print("\n" + "="*80)
        print("所有目录的文件MD5值完全一致！")
        print("="*80)
        return
    
    num_dirs = len(directories)
    print(f"\n" + "="*100)
    print(f"不一致的文件列表 (共比较 {num_dirs} 个目录):")
    print("="*100)
    
    for i, file_info in enumerate(inconsistent_files, 1):
        print(f"\n{i}. 文件: {file_info['file']}")
        
        # 打印每个目录的MD5值
        for j in range(1, num_dirs + 1):
            dir_name = file_info[f'dir{j}_name']
            md5_value = file_info[f'dir{j}_md5']
            print(f"   {dir_name}: {md5_value}")
        
        # 找出不一致的目录对
        diffs = []
        md5_values = [file_info[f'dir{k}_md5'] for k in range(1, num_dirs + 1)]
        
        for idx1 in range(num_dirs):
            for idx2 in range(idx1 + 1, num_dirs):
                if md5_values[idx1] != md5_values[idx2]:
                    dir1_name = file_info[f'dir{idx1+1}_name']
                    dir2_name = file_info[f'dir{idx2+1}_name']
                    diffs.append(f"{dir1_name} ≠ {dir2_name}")
        
        # if diffs:
        #     print(f"   不一致的目录对: {', '.join(diffs)}")
    
    print("\n" + "="*100)
    print(f"总计发现 {len(inconsistent_files)} 个不一致的文件")
    print("="*100)


def main(directories):
    """主函数"""
    # 检查目录是否存在
    for directory in directories:
        if not os.path.isdir(directory):
            print(f"错误: 目录 '{directory}' 不存在")
            sys.exit(1)
    
    print(f"开始比较 {len(directories)} 个目录的文件MD5值:")
    for i, directory in enumerate(directories, 1):
        print(f"目录{i}: {directory}")
    
    # 比较目录
    inconsistent_files, dirs_used = compare_directories(*directories)
    
    # 打印结果
    print_results(inconsistent_files, directories)


if __name__ == "__main__":
    component_paths = {
        "storage": [
            "/root/.conan/data/iam/1.0.12/openUBMC.release/dev/package/14da31e71d9b2a611ecc7a47161589e9be49c1e2",
            "/root/.conan/data/iam/1.0.11/openUBMC.release/dev/package/14da31e71d9b2a611ecc7a47161589e9be49c1e2"
        ]
    }
    for component, paths in component_paths.items():
        main(paths)


